from zope.interface import implements
from twisted.internet import interfaces, reactor
from twisted.internet.protocol import Factory, ClientFactory, ReconnectingClientFactory
from twisted.protocols.basic import LineReceiver
from twisted.internet.protocol import Protocol
from time import time
import os, sys
import ImageTk, Image
import random

class ClientInfo:

    def __init__(self):
        self.name = ''
        self.port = 0
        self.delay = 0

    def getName(self):
        return self.name

    def setName(self, name):
        self.name = name

    def setListenPort(self, port):
        self.port = port

    def getListenPort(self):
        return self.port

    def setDelay(self, delay):
        self.delay = delay

    def getDelay(self):
        return self.delay

class ContentProducer:
  implements(interfaces.IPushProducer)
  
  def __init__(self, protocol):
    self.protocol = protocol
    self.paused = False
    self.lineCount = 0
    self.startTime = None
    self.delay = 0.0
    self.vals = 0
    #self.image_path = os.path.join(os.getcwd(), 'images/')
    #self.dirlist = os.listdir(self.image_path)
    #self.CRate = 0
    #self.cname = ''
    
  def pauseProducing(self):
    print "ContentProducer paused"
    self.paused = True
    
  def resumeProducing(self):
    print "ContentProducer resuming"
    self.paused = False
    if not self.startTime:
      self.startTime = time()
    while not self.paused:
      #self.protocol.transport.write(str(getImageData(self))+"\r\n")
      self.protocol.transport.write("data:"+"Hello")  
      self.lineCount += 1
      if self.lineCount % 1000 == 0:
        print "rate = %.2f lines / second" % (self.lineCount / (time()-self.startTime))

  def stopProducing(self):
    pass
    
class NodeProtocol(LineReceiver):

  def connectionMade(self):
    print "%s.connectionMade" % self.factory.name
    self.producer = ContentProducer(self)  
    self.transport.registerProducer(self.producer, True)
    
  def lineReceived(self, line):
    clientInfo = ClientInfo()
    content = line.split()           
    if len(content) == 2:
        clientInfo.setName(str(content[0]))
        clientInfo.setListenPort(content[1])
        clientInfo.setDelay(random.randint(1, 10))
        connectionInfo = getToConnectClient()
        factory.clients.append(clientInfo)
        if not connectionInfo:
            self.producer.resumeProducing()
        else:
            self.transport.write(connectionInfo+"\r\n")
    else:
        self.transport.write("No enough information for connection to the server")
        self.transport.loseConnection()

  def connectionLost(self, reason):
    print "%s.connectionLost(%s)" % (self.factory.name, reason.getErrorMessage())

class NodeFactory(Factory):
  protocol = NodeProtocol
  isServer = True
  def __init__(self, name):
    self.name = name

def produceVal(self):
    self.vals += 1
    return self.vals


def getImageData(self):
    im_Name = "No more image"
    val = produceVal(self)
    if(len(self.dirlist) > val):
        im_Name = self.image_path+self.dirlist[val]
    return val

def getToConnectClient():
    delay = 10
    clientObj = ''
    if len(factory.clients) > 0:
        for client in factory.clients:
            if (client.getDelay() <= delay):
                delay = client.getDelay()
                clientObj = "connect:" + client.getName() + " " + client.getListenPort()
        #client = random.choice(factory.clients)
        return clientObj
    return 

port = 2000
factory = NodeFactory("Server")
factory.clients = []
reactor.listenTCP(port, factory)
print "Server running........."
reactor.run()
